package com.jlz.beans.core;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.jlz.beans.def.ColumnBean;
import com.julewa.db.DataType;
import com.julewa.db.StringTrimmer;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;

/**
 * 本类用以从http中构造DBObject, 处理DBObject的各种操作
 * @author Administrator
 *
 */
public class CategoryData extends BasicDBObject {
	private static final long serialVersionUID = 1L;
	private String prefix ;
	private Map<String, String[]> map;
	//
	public CategoryData(String prefix, ColumnBean root, Map<String, String[]> map){
		super.clear();
		this.prefix = prefix;
		this.map = map;
		List<ColumnBean> cols = root.getChildren();
		for(ColumnBean col: cols){
			this._build_(this, col);
		}
		this.map = null;
		this.prefix = null;
	}
	
	private void _build_(DBObject obj, ColumnBean col){
		if(col.isArray()){
			if(col.isComplex()){//复杂的结构耶,只允许有一层的说
				this._build_complex_array_(obj, col);
			}else{
				this._build_simple_array_(obj, col);
			}
		}else{
			if(col.isComplex()){
				this._build_complex_(obj, col);
			}else{
				this._build_simple_(obj, col);
			}
		}
		
	}
	
	//也就是说在http规则下,必须有唯一的名字才行.否则是不合法的
	private void _build_simple_(DBObject object, ColumnBean col){
		DataType dt = col.getValuetype().getDataType();
		switch(dt){
		case STRING:{
			String value = _one_(_get_(col));
			StringTrimmer st = col.getValuetype().getAutoTrimmer();
			if(st != null){
				value = st.trim(value);
			}
			//TODO check
			//col.checkDataState(value);
			object.put(col.getCode(), value);
		}return;
		default:
			String s = _one_(_get_(col));
			Object value = dt.convert(s);
			//TODO check
			//col.checkDataState(value);
			object.put(col.getCode(), value);
		}
	}
	
	private void _build_complex_(DBObject object, ColumnBean col){
		List<ColumnBean> cols = col.getChildren();
		BasicDBObject obj = new BasicDBObject();
		object.put(col.getCode(), obj);
		prefix +=  col.getCode() + ".";
		for(ColumnBean c:cols){
			this._build_(obj, c);
		}
	}
	
	private class Datas{
		public String[] array;
		public DataType type;
		public ColumnBean col;
		public Datas(ColumnBean col){
			this.col = col;
			this.array = _get_(col);
			this.type = col.getValuetype().getDataType();
		}
		public boolean isValid(){
			return array != null && array.length > 0;
		}
		public Object get(int index){
			//TODO check
			return type.convert(array[index]);
		}
	}
	
	//这个结构只允许有一层,否则增加处理的麻烦
	//且从实用的角度来看也并无益处
	private void _build_complex_array_(DBObject object, ColumnBean col){
		List<ColumnBean> cols = col.getChildren();
		Datas ds[] = new Datas[cols.size()];
		int size = -1;
		for(int i = 0; i < ds.length; i ++){
			ds[i] = new Datas(cols.get(i)); 
			if(size < 0 || size > ds[i].array.length){
				size = ds[i].array.length;
			}
		}
		List<Object> ls = new ArrayList<Object>();
		for(int i = 0; i < size; i ++){
			DBObject obj = new BasicDBObject();
			for(Datas d:ds){
				obj.put(d.col.getCode(), d.get(i));
			}
			ls.add(obj);
		}
		object.put(col.getCode(), ls);
	}
	
	private void _build_simple_array_(DBObject object, ColumnBean col){
		Datas ds = new Datas(col);
		if(!ds.isValid())return;
		List<Object> ls = new ArrayList<Object>();
		for(int idx = 0; idx < ds.array.length; idx ++){
			Object val = ds.get(idx);
			ls.add(val);
		}
		object.put(col.getCode(), ls);
	}
	
	
	///
	private String[] _get_(ColumnBean col){
		return map.get(prefix + col.getFullCode());
	}
	
	private String _one_(String ds[]){
		if(ds == null || ds.length < 1)return "";
		return ds[0];
	}
 
}
